import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.Data;

import java.io.*;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName Generator
 * @Description TDD
 * @Author 混沌酱
 * @Date 2023-08-09 17:27
 * @Version 1.0
 **/
@Data
public class Generator {

    private String url;
    private String user;
    private String password;

    private String entityAddress;
    private String repositoryAddress;
    private String swagger;
    private SqlOperate sqlOperate;
    private String tableName;


    public Generator(Builder builder) {
        this.url = builder.url;
        this.user = builder.user;
        this.password = builder.password;
        this.entityAddress=builder.entityAddress;
        this.repositoryAddress=builder.repositoryAddress;
        this.swagger=builder.swagger;
        this.tableName=builder.tableName;
        sqlOperate=new SqlOperate(url,user,password);
    }

    public static class Builder {
        public String url;
        public String user;
        public String password;

        private String entityAddress;
        private String repositoryAddress;
        private String swagger;
        private String tableName;

        public Builder(String url,String user,String password) {
            this.url = url;
            this.user = user;
            this.password = password;
        }

        public Builder setSwagger(String swagger){
            this.swagger=swagger;
            return this;
        }

        public Builder setEntityAddress(String entityAddress){
            this.entityAddress=entityAddress;
            return this;
        }

        public Builder setRpositoryAddress(String repositoryAddress){
            this.repositoryAddress=repositoryAddress;
            return this;
        }

        public Builder setTableName(String tableName){
            this.tableName=tableName;
            return this;
        }

        public Generator build(){
            return new Generator(this);
        }
    }

    /**
    *  生成代码
    * */
    public void exec(){
        GetTableName().forEach(x->{
            try {
                entity(x);
                repository(x);
            } catch (IOException | TemplateException | SQLException e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 数据表名
    * */
    public List<String> GetTableName(){
        List<String> list=new ArrayList<>();
        if (tableName.equals("*")){
            list=sqlOperate.getTables();
        }else {
            list.add(tableName);
        }
        return list;
    }


    /**
    * 实体类生成
    * */
    public void entity(String tableName) throws IOException, TemplateException {
        Configuration configurationEntity = new Configuration();
        Writer out = null;
        configurationEntity.setDirectoryForTemplateLoading(new File(GeneratorConstant.TEMPLATE_PATH));
        Template template = configurationEntity.getTemplate(GeneratorConstant.TEMPLATE_ENTITY);
        File docFile = new File(GeneratorConstant.TEMPLATE_JAVA_PATH+entityAddress + "\\" + Utils.converHump(tableName) + ".java");
        if(!docFile.getParentFile().exists()){
            docFile.getParentFile().mkdirs();
        }
        out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
        Map<String, Object> entityMap = new HashMap<String, Object>();
        entityMap.put("entitys", sqlOperate.getAttribute(tableName));
        entityMap.put("tableName", tableName);
        entityMap.put("swagger", swagger);
        entityMap.put("package",entityAddress.substring(1,entityAddress.length()).replace("/","."));
        template.process(entityMap, out);
    }


    /**
     * service生成
     * */
    public void repository(String tableName) throws IOException, TemplateException, SQLException {
        Configuration configuration = new Configuration();
        Writer out = null;
        configuration.setDirectoryForTemplateLoading(new File(GeneratorConstant.TEMPLATE_PATH));
        Template template = configuration.getTemplate(GeneratorConstant.TEMPLATE_RESPOSITORY);
        File docFile = new File(GeneratorConstant.TEMPLATE_JAVA_PATH+repositoryAddress + "\\" + Utils.converHump(tableName) + "Repository.java");
        if(!docFile.getParentFile().exists()){
            docFile.getParentFile().mkdirs();
        }
        out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(docFile)));
        Map<String, Object> repositoryMap = new HashMap<String, Object>();
        repositoryMap.put("tableName", tableName);
        repositoryMap.put("primaryKey",sqlOperate.primaryKey(tableName));
        repositoryMap.put("package",repositoryAddress.substring(1,repositoryAddress.length()).replace("/","."));
        repositoryMap.put("entityPath",entityAddress.substring(1,entityAddress.length()).replace("/","."));
        template.process(repositoryMap, out);
    }



}
